<template>
  <div>
    <el-table :data="newRelatedFormData" :header-cell-style="{background:'#eef1f6',color:'#606266'}" style="width: 100%;">
      <el-table-column
        v-if="relatedFormHeader.length > 0"
        :width="relatedFormHeader.length > 1 ? 40: 'auto'"
        align="center"
        fixed="left"
      >
        <template slot-scope="scope">
          <i class="el-icon-delete" @click="deleteRelatedFormData(scope.$index,scope.row.mongoDataId)"/>
        </template>
      </el-table-column>
      <!--关联表单表头-->
      <!-- 分页/区段/关联表单/html/富文本 无需关联 -->
      <!--      v-if="col.type !== 'paging' && col.type !== 'grid' && col.type !== 'relatedForm' && col.type !== 'html' && col.type !== 'editor'"-->
      <el-table-column
        v-for="col in relatedFormHeader"
        v-if="col.type !== 'autonumber'"
        :key="col.dataKey"
        min-width="200px"
      >
        <template slot="header" slot-scope="scope">
          {{ col.name }} <i v-if="col.options.required" class="red">*</i>
        </template>
        <!--关联表单数据-->
        <template slot-scope="scope">
          <div v-if="col.type === 'input' || col.type === 'textarea'">
            <el-input
              :placeholder="col.options.placeholder || ('请输入'+col.name)"
              v-model="scope.row[col.dataKey]"
              clearable
              @change="refreshRelatedFormData(scope.$index, scope.row, col)"/>
          </div>
          <div v-else-if="col.type === 'number'">
            <el-row>
              <el-col :span="18">
                <el-input-number
                  v-model="scope.row[col.dataKey]"
                  :step="col.options.step"
                  :controls="false"
                  :placeholder="col.options.placeholder|| ('请输入'+col.name)"
                  :disabled="!edit || col.options.disabled"
                  :min="col.options.numericalRange ? col.options.min : -Infinity"
                  :max="col.options.numericalRange ? col.options.max : Infinity"
                  :precision="col.options.integer ? 0 : col.options.float"
                  style="width:100%;"
                  @change="refreshRelatedFormData(scope.$index, scope.row, col)"
                />
              </el-col>
              <el-col :span="6" align="center">
                <span v-if="col.options.unit !== ''" class="unitRelative"> {{ col.options.unit }}</span>
              </el-col>
            </el-row>
          </div>
          <div v-else-if="col.type === 'imgupload' || col.type === 'fileupload'">
            <div class="upload-box" @click="formImgDialogOpen(scope.row[col.dataKey], col,scope.row,scope.$index)">
              <span v-if="scope.row[col.dataKey] && scope.row[col.dataKey].length" class="has-data">已选择 {{ scope.row[col.dataKey].length }} {{ col.type === 'imgupload'?'张图片':'个文件' }}</span>
              <span v-else>{{ col.type === 'imgupload' ? '选择图片' : '选择文件' }}</span>
              <i :class="[col.type === 'imgupload'?'el-icon-picture-outline':'iconattachment icon iconfont']"/>
            </div>
          </div>
          <div v-else-if="col.type === 'radio'">
            <el-select
              v-model="scope.row[col.dataKey]"
              :placeholder="col.options.placeholder || '请选择'"
              @change="refreshRelatedFormData(scope.$index, scope.row, col)">
              <el-option
                v-for="item in col.options.options"
                :key="item.value"
                :label="item.label"
                :value="item.value"
                clearable/>
            </el-select>
          </div>
          <div v-else-if="col.type === 'checkbox'">
            <el-select v-model="scope.row[col.dataKey]" :placeholder="col.options.placeholder || '请选择'" multiple collapse-tags @change="refreshRelatedFormData(scope.$index, scope.row, col)">
              <el-option
                v-for="item in col.options.options"
                :key="item.value"
                :label="item.label"
                :value="item.value"
                clearable
              />
            </el-select>
          </div>
          <div v-else-if="col.type === 'switch'">
            <el-switch v-model="scope.row[col.dataKey]" @change="refreshRelatedFormData(scope.$index,scope.row, col)"/>
          </div>
          <!--日期-->
          <div v-else-if="col.type === 'date'">
            <el-date-picker
              v-model="scope.row[col.dataKey]"
              :type="col.options.type"
              :placeholder="col.options.placeholder || '请选择日期'"
              style="width: 100%"
              @change="refreshRelatedFormData(scope.$index, scope.row, col)"
            />
          </div>
          <!-- 成员 -->
          <div v-else-if="col.type === 'member'">
            <member
              v-model="scope.row[col.dataKey]"
              :member-range="col.options.memberRange"
              :disabled="col.options.disabled"
              :multiple="col.options.multiple"
              :placeholder="col.options.placeholder || ('请选择'+col.name) "
              @change="refreshRelatedFormData(scope.$index, scope.row, col)"
            />
          </div>
          <!--关联选项-->
          <div v-else-if="col.type === 'relatedChoice'">
            <relate-choice v-model="scope.row[col.dataKey]" :widget="col" width="100%" from="relatedForm" @change="refreshRelatedFormData(scope.$index, scope.row, col)"/>
          </div>
          <!-- 地理区域 -->
          <div v-else-if="col.type === 'cascader'">
            <province-city-county
              :type="col.options.type"
              v-model="scope.row[col.dataKey]"
              :is-default="true"
              :disabled="col.options.disabled"
              from="generator"
              @change="refreshRelatedFormData(scope.$index, scope.row, col)"
            />
          </div>
          <span v-if="scope.row.mongoDataIds || showWarm" class="red">{{ scope.row.warmText[col.dataKey] }}</span>
        </template>
      </el-table-column>
    </el-table>
    <el-dialog
      :title="relatedFormDialog.info.name"
      :visible.sync="relatedFormDialog.dialogVisible"
      width="50%">
      <span>
        <fm-upload
          v-if="relatedFormDialog.info.type === 'imgupload'"
          v-model="relatedFormDialog.dataModel"
          :multiple="relatedFormDialog.info.options.multiple"
          :limit="relatedFormDialog.info.options.limit"
          :file-size="relatedFormDialog.info.options.fileSize"
          :key="relatedFormDialog.row.mongoDataId"
        />
        <file-upload
          v-if="relatedFormDialog.info.type === 'fileupload'"
          v-model="relatedFormDialog.dataModel"
          :multiple="relatedFormDialog.info.options.multiple"
          :limit="relatedFormDialog.info.options.limit"
          :file-size="relatedFormDialog.info.options.fileSize"
          :key="relatedFormDialog.row.mongoDataId"/>
      </span>
      <span v-if="relatedFormDialog.info.type === 'imgupload'"> 最多可上传 {{ relatedFormDialog.info.options.limit }}张图片 ，且每张图片小于{{ relatedFormDialog.info.options.fileSize }}MB </span>
      <span v-if="relatedFormDialog.info.type === 'fileupload'"> 最多可上传 {{ relatedFormDialog.info.options.limit }}个文件 ，且每个文件小于{{ relatedFormDialog.info.options.fileSize }}MB </span>
      <span slot="footer" class="dialog-footer">
        <el-button @click="cancelDialog">取 消</el-button>
        <el-button type="primary" @click="comfirmAddImg">确 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>
<script>
import FmUpload from '../form/Upload'
import fileUpload from '../form/Upload/file'
import Member from '../member/index'
import ProvinceCityCounty from '../provinceCityCounty/index'
import relateChoice from '../relatedChoice'
import { formFieldList, getAppointData, getAllMenu } from '@/api/builder'
import { formDataDelete, formPageDataSubmit, formDataUpdate } from '@/api/list'
import { EventBus } from '@/util/event-bus.js'
export default {
  components: {
    FmUpload,
    Member,
    ProvinceCityCounty,
    fileUpload,
    relateChoice
  },
  props: {
    value: {
      type: Array,
      default: () => []
    },
    relatedFormData: {
      type: Array,
      default: () => []
    },
    edit: {
      type: Boolean,
      default: true
    },
    option: {
      type: Object,
      default: () => {}
    },
    from: {
      type: String, // 预览：'preview'  新增'add' 编辑：'edit'
      default: ''
    }
  },
  data() {
    return {
      mongoDataIds: this.value,
      newRelatedFormData: [], // 表格数据
      relatedFormHeader: [], // 表格标题
      relatedFormDialog: {
        // name: '',
        dialogVisible: false,
        dataModel: [],
        row: {},
        // action: '#'
        info: {
          options: {}
        }
      },
      templateDataId: '',
      formDateRules: {},
      isSubmit: true, // 当前数据是否能提交到后台 true 是 false 否
      showWarm: false // 是否显示提示文字 true 显示 false 不显示
    }
  },
  watch: {
    'mongoDataIds': {
      handler(val) {
        this.$emit('input', val)
      },
      deep: true
    },
    isSubmit(val) {
      EventBus.$emit('isSubmit', val)
    }
  },
  async created() {
    if (this.from === 'preview') {
      const res = await getAllMenu()
      this.templateDataId = res.body.filter(f => f.templateDataId === this.option.formId)[0].dataFromPage
    } else {
      this.templateDataId = this.$store.state.user.page.filter(f => f.templateDataId === this.option.formId)[0].dataFromPage
    }
    // 接收提交按钮返回的showWarm判断是否显示提示语
    EventBus.$on('showWarm', (data) => {
      this.showWarm = data
    })
    await this.getTableColumn()
    if (this.mongoDataIds.length) {
      const fieldIds = this.relatedFormHeader.map(item => item.dataKey)
      fieldIds.push('mongoDataId')
      const options = {
        appointFields: fieldIds,
        mongoDataIds: this.mongoDataIds
      }
      getAppointData(options).then(res => {
        this.newRelatedFormData = res.body
        this.newRelatedFormData.forEach(item => {
          this.$set(item, 'verify', {})
          this.$set(item, 'warmText', {})
          Object.keys(item).forEach(cItem => {
            this.relatedFormHeader.forEach(sItem => {
              item.verify[sItem.dataKey] = true
              if (sItem.dataKey === cItem && sItem.type === 'switch') {
                item[cItem] = !!item[cItem]
              }
            })
          })
        })
      })
    }
  },
  methods: {
    // 获取表头
    async getTableColumn() {
      const res = await formFieldList([this.templateDataId])
      this.formDateRules = {}
      res.body.map(m => {
        const dataKey = m.dataKey
        this.formDateRules[dataKey] = m.options
      })
      this.option.header.forEach(item => {
        res.body.forEach(cItem => {
          if (cItem.dataKey === item.dataKey) {
            this.relatedFormHeader.push(cItem)
          }
        })
      })
      // console.log(111,this.relatedFormHeader)
      // debugger
    },
    // 打开上传图片、文件弹框
    formImgDialogOpen(dataModel, info, row, index) {
      this.relatedFormDialog.row = row
      this.relatedFormDialog.info = info
      this.relatedFormDialog.dataModel = dataModel || []
      this.relatedFormDialog.dialogVisible = true
      this.$set(this.relatedFormDialog, 'rowIndex', index)
    },
    // 删除关联表单行
    deleteRelatedFormData(index, mongoDataId) {
      if (!mongoDataId) {
        this.newRelatedFormData.splice(index, 1)
        this.isSubmit = true
      } else {
        const data = [{
          templateDataId: this.templateDataId,
          mongoDataId: mongoDataId
        }]
        formDataDelete(data).then((res) => {
          if (res.code === 200) {
            this.$message.success('删除成功！')
            this.newRelatedFormData = this.newRelatedFormData.filter(item => item.mongoDataId !== mongoDataId)
            this.isSubmit = true
            this.formatMongoDataId()
          }
        })
      }
    },
    // 新增一行空数据
    addFromDate() {
      if (this.option.maxSize <= this.newRelatedFormData.length) {
        this.$message.error('最多' + this.option.maxSize + '项')
        return
      }
      if (this.from === 'preview') {
        this.$message.error('请前往生成器添加数据')
        return
      }
      if (!this.isSubmit) {
        this.showWarm = true
        this.$message.error('请完善表格')
        return
      }
      this.showWarm = false
      const verify = {} // true 验证通过 false 验证未通过
      const warmText = {}
      this.relatedFormHeader.forEach(item => {
        if (item.options.required) {
          verify[item.dataKey] = false
          warmText[item.dataKey] = item.name + '不能为空'
          this.isSubmit = false
        } else {
          verify[item.dataKey] = true
        }
        if (item.options.validateType === 'email' || item.options.validateType === 'name' || item.options.validateType === 'phone') {
          verify[item.dataKey] = false
        }
      })
      const obj = {}
      this.relatedFormHeader.map(m => obj[m.dataKey] = null)
      this.newRelatedFormData.push({
        ...obj,
        verify: verify,
        warmText: warmText
      })
      const flag = !Object.values(verify).some(s => s === false)
      EventBus.$emit('isSubmit', flag)
    },
    // 关联表单--后台新增一条数据
    addNewFormData(data, index) {
      const json = { pageDatas: data, dataFrom: this.$route.params.id }
      formPageDataSubmit(json).then(res => {
        if (res.code === 200) {
          this.$emit('change')
          this.newRelatedFormData[index].mongoDataId = res.body.mogoDataId[0]
          this.formatMongoDataId()
        }
      })
    },
    // 修改关联表单数据
    async refreshRelatedFormData(index, row, col) {
      this.showWarm = true
      for (let i = 0; i < this.relatedFormHeader.length; i++) {
        const item = this.relatedFormHeader[i]
        if (item.options.required && item.type !== 'switch') {
          if ((Array.isArray(row[item.dataKey]) && !row[item.dataKey].length) || (!row[item.dataKey] && row[item.dataKey] !== 0)) {
            this.$set(row.warmText, [item.dataKey], item.name + '不能为空')
            row.verify[item.dataKey] = false
            continue
          }
        } else {
          row.verify[item.dataKey] = true
          this.$set(row.warmText, [item.dataKey], '')
        }
        if (item.options.validateType === 'email') {
          const verEmail = new RegExp(/^([a-zA-Z]|[0-9])(\w|\-|\.)+@[a-zA-Z0-9]+\.([a-zA-Z]{2,4})$/)
          if (!verEmail.test(row[item.dataKey])) {
            this.$set(row.warmText, [item.dataKey], '邮箱格式不正确')
            row.verify[item.dataKey] = false
            continue
          }
        } else if (item.options.validateType === 'phone') {
          const verPhone = new RegExp(/^1[3-9](\d{9})$/)
          if (!verPhone.test(row[item.dataKey])) {
            this.$set(row.warmText, [item.dataKey], '手机格式不正确')
            row.verify[item.dataKey] = false
            continue
          }
        } else if (item.options.validateType === 'name') {
          const verPhone = new RegExp(/^([\u4e00-\u9fa5]{1,20}|[a-zA-Z\.\s]{1,20})$/)
          if (!verPhone.test(row[item.dataKey])) {
            this.$set(row.warmText, [item.dataKey], '姓名格式不正确')
            row.verify[item.dataKey] = false
            continue
          }
        } else {
          this.$set(row.warmText, [item.dataKey], '')
          row.verify[item.dataKey] = true
        }
      }
      const verArr = Object.values(row.verify)
      if (verArr.some(s => s === false)) {
        return
      }
      const allVerArr = this.newRelatedFormData.map(m => {
        if (Object.values(m.verify).some(s => s === false)) {
          return false
        }
      })
      this.isSubmit = !allVerArr.some(s => s === false)
      let data = []
      let pageData = JSON.parse(JSON.stringify(row))
      // console.log(pageData)
      // debugger
      delete pageData['_id']
      delete pageData['mongoDataId']
      delete pageData['verify']
      delete pageData['warmText']
      const dataKeyArr = this.relatedFormHeader.filter(f => f.type === 'switch')
      Object.keys(pageData).forEach(cItem => {
        dataKeyArr.forEach(sItem => {
          if (sItem.dataKey === cItem) {
            pageData[cItem] = pageData[cItem] ? 1 : 0
          }
        })
      })
      pageData = this.fomtterUploadData(pageData)
      data = [{
        templateDataId: this.templateDataId,
        mongoDataId: row.mongoDataId,
        pageData: pageData
      }]
      if (!row.mongoDataId) {
        this.addNewFormData(data, index)
      } else {
        await formDataUpdate(data)
        this.formatMongoDataId()
      }
    },
    // 上传图片成功
    async comfirmAddImg() {
      this.relatedFormDialog.dialogVisible = false
      const dataKey = this.relatedFormDialog.info.dataKey
      this.$set(this.relatedFormDialog.row, dataKey, this.relatedFormDialog.dataModel)
      await this.refreshRelatedFormData(this.relatedFormDialog.rowIndex, this.relatedFormDialog.row)
      this.cancelDialog()
    },
    // 整理数据
    formatMongoDataId() {
      this.mongoDataIds = this.newRelatedFormData.map(m => m.mongoDataId)
    },
    // 弹框取消按钮
    cancelDialog() {
      this.relatedFormDialog.dialogVisible = false
    },
    // 文件，成员，日期格式处理
    fomtterUploadData(data) {
      const models = JSON.parse(JSON.stringify(data))
      // 处理 文件 数据
      const fileDataKeys = this.relatedFormHeader.filter(f => f.type === 'fileupload').map(m => m.dataKey)
      if (fileDataKeys.length) {
        fileDataKeys.forEach(item => {
          if (models[item]) {
            models[item].forEach(cItem => {
              delete cItem.uid
              delete cItem.status
            })
          }
        })
      }
      // 处理成员数据
      const memberList = this.relatedFormHeader.filter(f => f.type === 'member')
      if (memberList.length) {
        memberList.forEach(item => {
          if (!item.options.multiple && models[item.dataKey]) {
            models[item.dataKey] = [models[item.dataKey]]
          }
        })
      }
      // 处理日期
      const dateKeys = this.relatedFormHeader.filter(f => f.type === 'date').map(m => m.dataKey)
      if (dateKeys.length) {
        dateKeys.forEach(item => {
          if (models[item]) {
            models[item] = new Date(models[item]).toJSON()
          }
        })
      }
      return models
    }
  }
}
</script>
<style scoped>
  .el-icon-delete{display: none;}
  .hover-row .el-icon-delete{display: block;color:#f76364;}
  .upload-box{display: flex;justify-content: space-between;border:1px solid #dedede;height: 32px;line-height:32px;padding:0 10px; color:#b7bcc5;background: #FFFFFF;}
  .has-data{color:#606266;}
  .el-icon-picture-outline{font-size:16px;line-height:28px;}
  .el-dialog__body{padding:10px 20px !important;}
  .el-icon-delete{padding-top:10px;}
  .unitRelative { line-height:30px; }
</style>
<style>
  .content .el-table--mini td,.content .el-table--mini th{vertical-align:top;}
</style>
